Skip to content

entry: flush fscache after creating directories and writing files#6250

Merged
dscho merged 1 commit into
git-for-windows:mainfrom
tyrielv:tyrielv/fscache-parallel-checkout-fix-gfw
Jun 8, 2026
Merged

entry: flush fscache after creating directories and writing files#6250
dscho merged 1 commit into
git-for-windows:mainfrom
tyrielv:tyrielv/fscache-parallel-checkout-fix-gfw

Conversation

@tyrielv

@tyrielv tyrielv commented May 18, 2026

Copy link
Copy Markdown

Problem

git checkout <tree> -- <pathspec> with checkout.workers > 1 and core.fscache=true fails when restoring files into directories that do not yet exist on disk. Two failure modes:

  1. fatal: cannot create directory at '...': Directory not empty (exit 128)
  2. error: unable to stat just-written file '...' (exit 255)

100% reproducible when two or more files share a not-yet-created parent directory.

Root Cause

The Windows fscache caches directory listings that become stale when create_directories() creates new parent directories via mkdir() or when write_pc_item() writes new files. With workers=1, write_entry() calls flush_fscache() after each file, keeping the cache in sync. With workers>1, enqueue_checkout() defers the write (and the flush), leaving the cache stale for subsequent entries.

Fix

Add flush_fscache() calls:

  • In create_directories() after each successful mkdir(), so has_dirs_only_path() sees the new directory
  • In write_pc_item() before lstat() of the just-written file

On non-Windows platforms flush_fscache() is a no-op.

Test

Adds a regression test to t2080-parallel-checkout-basics.sh (MINGW prereq) that deterministically reproduces the bug: two files sharing a nested parent directory, deleted in a second commit, then restored via git checkout <tree> -- <pathspec> with workers=2.

When checkout.workers > 1 and core.fscache is enabled on Windows,
'git checkout <tree> -- <pathspec>' fails when restoring files into
directories that do not yet exist on disk. Two failure modes occur:

1. create_directories(): the fscache returns a stale directory listing
   that does not include a just-created directory. has_dirs_only_path()
   reports it as non-existent, triggering the unlink+mkdir recovery
   path which fails with 'cannot create directory: Directory not empty'.

2. write_pc_item(): after writing and closing a file, lstat() cannot
   see it through the stale fscache, failing with 'unable to stat
   just-written file'.

With workers=1, write_entry() calls flush_fscache() after each file,
keeping the cache in sync. With workers>1, enqueue_checkout() defers
the write (and the flush), leaving the cache stale for subsequent
entries.

Fix both by adding flush_fscache() calls after mkdir() in
create_directories() and before lstat() in write_pc_item(). On
non-Windows platforms flush_fscache() is a no-op.

Assisted-by: Claude Opus 4.6
Signed-off-by: Tyrie Vella <tyrielv@gmail.com>
@tyrielv tyrielv marked this pull request as ready for review May 18, 2026 17:08
@dscho dscho added this to the Next release milestone Jun 8, 2026
@dscho dscho merged commit 33d828c into git-for-windows:main Jun 8, 2026
115 of 117 checks passed
@dscho

dscho commented Jun 8, 2026

Copy link
Copy Markdown
Member

/add relnote bug A bug was fixed which could cause parallel checkouts to fail under certain circumstances when the FSCache is enabled.

The workflow run was started

github-actions Bot pushed a commit to git-for-windows/build-extra that referenced this pull request Jun 8, 2026
A bug was [fixed](git-for-windows/git#6250)
which could cause parallel checkouts to fail under certain circumstances
when the FSCache is enabled.

Signed-off-by: gitforwindowshelper[bot] <gitforwindowshelper-bot@users.noreply.github.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants